package chatGUI;

/**
 *
 * @author deepali and vansh
 */
import java.awt.BorderLayout;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;

import chatModel.Conversation;
import chatModel.User;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import signals.SignalTooBigException;

public class ChatWindow extends JFrame implements ActionListener {

    protected DefaultListModel usersListModel;
    protected JList usersList;
    protected JButton sendMessage;
    protected JButton sendFile, disconnect;
    protected JTextField messageBox;
    protected JTextArea chatBox;
    protected Calendar cal;
    protected JScrollPane chatPane, inputPane, listPane, userInputPane, userChatPane;
    protected JPanel window;
    protected JLabel loginLabel, listLabel, infoLabel;
    protected JTextArea inputArea;
    protected String formattedText, formattedUsername, selectedUser;
    protected JTextField usernameField;
    private ArrayList<ConversationArea> conversations;
    protected JFrame frame;
    public JTabbedPane tabbedPane = new JTabbedPane();
    protected JTextPane editorPane;
    protected ChatGui cg;
    protected JList list;
    protected static int i = 1;
    protected String[] tableau;
    protected StyledDocument doc;

    /**
     * This class allows use open the chat window
     *
     */
    public ChatWindow(ChatGui cg) {
        super();
        this.cg = cg;
        tableau = new String[100];
        this.display();
    }

    public void display() {

        usersListModel = new DefaultListModel();
        usersList = new JList(usersListModel);

        /**
         * It selects the user on which the LocalUser double clicks from the
         * list of connected user
         */
        usersList.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent arg0) {
                if (arg0.getClickCount() == 2) {
                    System.out.println("I am here");
                    selectedUser = (String) usersList.getSelectedValue();
                    // formattedUsername = usernameField.getText().trim();
                    if ((selectedUser.equals("         Welcome " + cg.cm.getLocalUser().getUsername()))) {

                    } else if ((selectedUser.equals(" ------------------------------------- "))) {

                    } else if ((selectedUser.equals("       Connected Users :"))) {
                    } else if (usersList.getSelectedValue() != null) {
                        System.out.println("click");
                    }

                    System.out.println((String) usersList.getSelectedValue());
                    System.out.println(i);
                    if (i == 1) {
                        System.out.println(usersList.getSelectedValue());
                        cg.cc.performUserSelected((String) usersList.getSelectedValue());
                    } else {
                        int j;
                        boolean bool = false;
                        {
                            cg.cc.performUserSelected((String) usersList.getSelectedValue());
                        }
                    }
                }

            }

            @Override
            public void mouseEntered(MouseEvent arg0) {
                                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent arg0) {
                                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent arg0) {
                                // TODO Auto-generated method stub

            }

            @Override
            public void mouseReleased(MouseEvent arg0) {
                                // TODO Auto-generated method stub

            }
        });

        window = new JPanel();

        inputArea = new JTextArea();

        listPane = new JScrollPane(usersList);
        listPane.setBounds(437, 78, (675 - 447), (544 - 78));
        listPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        listLabel = new JLabel("List of Connected Users");
        listLabel.setForeground(Color.RED);
        listLabel.setBounds(444, 34, (675 - 447), (62 - 26));

        inputPane = new JScrollPane(inputArea);
        inputPane.setBounds(20, 562, (545 - 30), (604 - 555));
        inputPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        JFrame chatw = new JFrame("Chat System");
        JPanel southPanel = new JPanel();

        chatw.getContentPane().add(BorderLayout.SOUTH, southPanel);
        southPanel.setBackground(Color.gray);
        southPanel.setLayout(new GridBagLayout());

        JMenuBar mb = new JMenuBar();
        JMenu m1 = new JMenu("FILE");
        JMenu m2 = new JMenu("Help");
        mb.add(m1);
        mb.add(m2);
        JMenuItem m11 = new JMenuItem("Open");
        JMenuItem m22 = new JMenuItem("Save as");
        m1.add(m11);
        m1.add(m22);

        messageBox = new JTextField(20);

        sendMessage = new JButton("Send Message");
        sendFile = new JButton("Send File");

        sendFile.addActionListener(new ActionListener() {

            /**
             * Action performed when sendFile button is clicked
             *
             * @param e
             */
            public void actionPerformed(ActionEvent e) {
                if ((tabbedPane.getSelectedIndex() > 0)) {
                    String nom = tableau[tabbedPane.getSelectedIndex()];
                    JFileChooser filechooser = new JFileChooser();
                    int val = filechooser.showOpenDialog(rootPane);
                    if (val == JFileChooser.APPROVE_OPTION) {
                        System.out.println("You chose to send this file: "
                                + filechooser.getSelectedFile().getAbsolutePath() + " to " + tabbedPane.getTitleAt(tabbedPane.getSelectedIndex()));
                        try {
                            cg.cc.performSendFileRequest(nom, filechooser.getSelectedFile().getName(), filechooser.getSelectedFile().getAbsolutePath());
                        } catch (SignalTooBigException ex) {
                            Logger.getLogger(ChatWindow.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (IOException ex) {
                            Logger.getLogger(ChatWindow.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }

                //Execute when button is pressed
                System.out.println("You clicked the button");
            }
        });

        disconnect = new JButton("Disconnect");
        chatBox = new JTextArea(10, 10);
        chatBox.setEditable(false);

        southPanel.add(messageBox);
        southPanel.add(sendMessage);
        southPanel.add(sendFile);
        southPanel.add(disconnect);
        sendMessage.addActionListener(this);
        disconnect.addActionListener(this);

        chatw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        chatw.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent windowEvent) {
                try {
                    cg.cc.performDisconnect();
                } catch (SignalTooBigException ex) {
                    Logger.getLogger(ChatWindow.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(ChatWindow.class.getName()).log(Level.SEVERE, null, ex);
                }
                System.out.println("Disconnection");
            }
        });

        chatw.getContentPane().add(BorderLayout.EAST, listPane);

        chatw.add(new JScrollPane(chatBox), BorderLayout.CENTER);
        chatw.getContentPane().add(BorderLayout.NORTH, mb);

        chatBox.setLineWrap(true);

        Font font = new Font("Arial", Font.BOLD, 15);

        chatw.add(tabbedPane, BorderLayout.CENTER);

        editorPane = new JTextPane();
        editorPane.setFont(font);
        editorPane.setText("");
        editorPane.setForeground(Color.gray);
        tabbedPane.addTab("First", null);
        tabbedPane.setTitleAt(0, "Please choose a contact");
        tabbedPane.setBackgroundAt(0, Color.GRAY);
        tabbedPane.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                System.out.println("Tab: " + tabbedPane.getSelectedIndex());

            }
        });

////        
        usersListModel.addElement("         Welcome " + cg.cm.getLocalUser().getUsername());
        usersListModel.addElement(" ------------------------------------- ");
        usersListModel.addElement("       Connected Users :");
        for (int i = 0; i < cg.cm.getConnectedUsers().getSize(); i++) {
            usersListModel.addElement(cg.cm.getConnectedUsers().getElementAt(i));
        }

        chatw.setSize(670, 500);
        chatw.setVisible(true);
        doc = editorPane.getStyledDocument();

    }

    /**
     * action performed when SendMsg button is clicked
     *
     * @param event
     */
    public void actionPerformed(ActionEvent event) {
        if (event.getSource() == (sendMessage) & (tabbedPane.getSelectedIndex() > 0)) {
            if (messageBox.getText().length() < 1) {
                // do nothing 
            } else {
                cal = Calendar.getInstance();
                cal.getTime();
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                try {
                    String nom = tableau[tabbedPane.getSelectedIndex()];
                    System.out.println("Here is the name of the user on tabbedpane " + nom);
                    JTextPane editorPane = (JTextPane) tabbedPane.getSelectedComponent();
                    StyledDocument doc = editorPane.getStyledDocument();
                    doc.insertString(doc.getLength(), "Me:" + sdf.format(cal.getTime()) + ":\n", null);
                    doc.insertString(doc.getLength(), messageBox.getText() + "\n", null);
                    try {
                        cg.cc.performSendMessage(nom, messageBox.getText());
                    } catch (SignalTooBigException ex) {
                        Logger.getLogger(ChatWindow.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } catch (BadLocationException err) {
                    // TODO Auto-generated catch block
                    err.printStackTrace();
                }
                messageBox.setText("");
            }

        }
        if (event.getSource() == disconnect) {
            try {
                cg.cc.performDisconnect();
            } catch (SignalTooBigException ex) {
                Logger.getLogger(ChatWindow.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(ChatWindow.class.getName()).log(Level.SEVERE, null, ex);
            }
            cg.close();
        }

    }

    /**
     * To open a conversation with user clicked on
     *
     * @param c
     */
    public void openConversation(Conversation c) {

        if (c.getRemoteUser() == null) {
            System.out.println("a");
        }
        if (c.getRemoteUser().getUsername() == null) {
            System.out.println("b");
        }
        if (tableau[tabbedPane.getSelectedIndex()] == null) {
            System.out.println("c");
        }
        User remoteuser = c.getRemoteUser();
        for (int i = 0; i < tabbedPane.getTabCount(); i++) {
            if ((remoteuser.getUsername() + "@" + remoteuser.getHostname()).equalsIgnoreCase(tabbedPane.getTitleAt(i))) {
                tabbedPane.setSelectedIndex(i);
                System.out.println("SelectedIndex" + i);
                break;
            }
        }
        if (!c.getRemoteUser().getUsername().equals(tableau[tabbedPane.getSelectedIndex()])) {
            tabbedPane.addTab(c.getRemoteUser().toString(), new ConversationArea(c));
            tabbedPane.setSelectedIndex(i);
            i++;
            tableau[tabbedPane.getSelectedIndex()] = c.getRemoteUser().getUsername();
        }

    }

    /**
     * It selects a remote user from the list and creates a conversation with it
     *
     * @param remoteUser
     */
    public void performUserSelected(User remoteUser) {
        Conversation c = new Conversation(remoteUser);
        cg.cm.addConversations(c);
        cg.addTab(c);
    }

    /**
     * the method returns the userlistmodel
     *
     * @return
     */
    public DefaultListModel getUsersListModel() {
        return usersListModel;
    }

    /**
     * the method notifies the user when remote user tries to send a file
     *
     * @param username
     */
    public void notifyBeforFileSent(String username) {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        for (int i = 0; i < cg.getChatwindow().tabbedPane.getTabCount(); i++) {
            if ((username.split("@")[0]).equalsIgnoreCase(cg.getChatwindow().tabbedPane.getTitleAt(i).split("@")[0])) {
                cg.getChatwindow().tabbedPane.setSelectedIndex(i);
                System.out.println("SelectedIndex" + i);
                break;
            }
        }
        JTextPane editorPane = (JTextPane) tabbedPane.getSelectedComponent();
        StyledDocument doc = editorPane.getStyledDocument();
        try {
            doc.insertString(doc.getLength(), "There is a file transfer demand from " + username + "\n", null);
        } catch (BadLocationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * the method notifies the user when it has completed receiving the file
     *
     * @param username
     */
    public void notifyFileRcvd(String username) {
        cal = Calendar.getInstance();
        cal.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        for (int i = 0; i < cg.getChatwindow().tabbedPane.getTabCount(); i++) {
            if ((username.split("@")[0]).equalsIgnoreCase(cg.getChatwindow().tabbedPane.getTitleAt(i).split("@")[0])) {
                cg.getChatwindow().tabbedPane.setSelectedIndex(i);
                System.out.println("SelectedIndex" + i);
                break;
            }

            System.out.println("Atindex" + i);

        }
        JTextPane editorPane = (JTextPane) tabbedPane.getSelectedComponent();
        StyledDocument doc = editorPane.getStyledDocument();
        try {
            doc.insertString(doc.getLength(), "You have received a file from " + username + " " + " at:" + " " + sdf.format(cal.getTime()) + ", It is in your home directory\n", null);
        } catch (BadLocationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * This method notifies the local user when it has completed sending the
     * file
     *
     * @param username
     */
    public void notifyFileSent(String username) {
        cal = Calendar.getInstance();
        cal.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        JTextPane editorPane = (JTextPane) tabbedPane.getSelectedComponent();
        StyledDocument doc = editorPane.getStyledDocument();
        try {
            doc.insertString(doc.getLength(), "Your file have been sent to " + username + " " + " at:" + " " + sdf.format(cal.getTime()) + "\n", null);
        } catch (BadLocationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void addMessagercvd(String msg, String username) {
        cal = Calendar.getInstance();
        cal.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        try {
            System.out.println("----------------------addmsgrcvd------------------");
            System.out.println("messageBox.getText() ");
            JTextPane editorPane = (JTextPane) tabbedPane.getSelectedComponent();
            StyledDocument doc = editorPane.getStyledDocument();
            doc.insertString(doc.getLength(), username + " " + "says at:" + " " + sdf.format(cal.getTime()) + ":\n", null);
            doc.insertString(doc.getLength(), msg + "\n", null);
            Conversation c = cg.cm.getHashmapConv().get(username);

        } catch (BadLocationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * This method updates the list of connected users
     *
     * @param username
     */
    public void updateUsersList(String username) {
        // TODO Auto-generated method stub
        usersListModel.addElement(username);
    }

    /**
     * This method removes the remote user from the list of connected users when
     * the remote user disconnects
     *
     * @param username
     */
    public void removeUser(String username) {
        System.out.println("on doit supprimer l'utilisateur ici");
        usersListModel.removeElement(username);
        tabbedPane.remove(tabbedPane.getSelectedComponent());
        i--;
    }

}
